home *** CD-ROM | disk | FTP | other *** search
/ Aminet 12 / Aminet 12 (1996)(GTI - Schatztruhe)[!][Jun 1996].iso / Aminet / gfx / show / gs_src_amiga.lha / gp_amiga.c < prev    next >
C/C++ Source or Header  |  1996-03-05  |  13KB  |  580 lines

  1. /* Copyright (C) 1989, 1992, 1993, 1994 Aladdin Enterprises.  All rights reserved.
  2.  
  3.   This file is part of Aladdin Ghostscript.
  4.  
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.  
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* gp_amiga.c */
  20. /* Amiga-specific routines for Ghostscript */
  21. #include <intuition/intuitionbase.h>
  22. #include <graphics/gfxbase.h>
  23. #include <dos/dosextens.h>
  24.  
  25. #include <proto/exec.h>
  26. #include <proto/dos.h>
  27.  
  28. #include "string_.h"
  29. #include "gx.h"
  30. #include "gsexit.h"
  31. #include "gp.h"
  32. #include "time_.h"
  33.  
  34. #include <signal.h>
  35. #include <stdio.h>
  36.  
  37. /* Library routines not declared in a standard header */
  38. extern char *getenv(P1(const char *));
  39. /* Because of inconsistent (and sometimes incorrect) header files, */
  40. /* we must omit the argument list. */
  41. #ifdef IXEMUL
  42. extern FILE *popen(  P2(const char *, const char *)  );
  43. extern int pclose(P1(FILE *));
  44. #endif
  45.  
  46. struct IntuitionBase    *IntuitionBase;
  47. struct GfxBase        *GfxBase;
  48. struct Library        *LayersBase,
  49.             *IFFParseBase,
  50.             *AslBase,
  51.             *UtilityBase;
  52.  
  53. #ifdef IXEMUL
  54. const char gp_null_file_name[] = "/NIL";
  55. const char gp_current_directory_name[] = ".";
  56. #else
  57. const char gp_null_file_name[] = "NIL:";
  58. const char gp_current_directory_name[] = "";
  59. #endif
  60.  
  61. /* Cleanup routine, as called by atexit() trap */
  62. void
  63. cleanup()
  64. {
  65.     extern void devcleanup();
  66.  
  67.     devcleanup();
  68.  
  69.     if(IFFParseBase)
  70.     {
  71.         CloseLibrary(IFFParseBase);
  72.  
  73.         IFFParseBase = NULL;
  74.     }
  75.  
  76.     if(AslBase)
  77.     {
  78.         CloseLibrary(AslBase);
  79.  
  80.         AslBase = NULL;
  81.     }
  82.  
  83.     if(UtilityBase)
  84.     {
  85.         CloseLibrary(UtilityBase);
  86.  
  87.         UtilityBase = NULL;
  88.     }
  89.  
  90.     if(LayersBase)
  91.     {
  92.         CloseLibrary(LayersBase);
  93.  
  94.         LayersBase = NULL;
  95.     }
  96.  
  97.     if(GfxBase)
  98.     {
  99.         CloseLibrary((struct Library *)GfxBase);
  100.  
  101.         GfxBase = NULL;
  102.     }
  103.  
  104.     if(IntuitionBase)
  105.     {
  106.         CloseLibrary((struct Library *)IntuitionBase);
  107.  
  108.         IntuitionBase = NULL;
  109.     }
  110. }
  111.  
  112. void
  113. signal_handler(int signal)
  114. {
  115.     fprintf(stderr,"*** BREAK: Ghostscript\a\n");
  116.  
  117.     exit(1);
  118. }
  119.  
  120. /* Do platform-dependent initialization. */
  121. void
  122. gp_init(void)
  123. {
  124.     atexit(cleanup);
  125.  
  126.     signal(SIGINT,signal_handler);
  127.  
  128.     if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)))
  129.     {
  130.         perror("Ghostscript: cannot open intuition.library v37");
  131.  
  132.         exit(20);
  133.     }
  134.  
  135.     if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37)))
  136.     {
  137.         perror("Ghostscript: cannot open graphics.library v37");
  138.  
  139.         exit(20);
  140.     }
  141.  
  142.     if(!(LayersBase = OpenLibrary("layers.library",37)))
  143.     {
  144.         perror("Ghostscript: cannot open layers.library v37");
  145.  
  146.         exit(20);
  147.     }
  148.  
  149.     if(!(UtilityBase = OpenLibrary("utility.library",37)))
  150.     {
  151.         perror("Ghostscript: cannot open utility.library v37");
  152.  
  153.         exit(20);
  154.     }
  155.  
  156.     if(!(IFFParseBase = OpenLibrary("iffparse.library",37)))
  157.     {
  158.         perror("Ghostscript: cannot open iffparse.library v37");
  159.  
  160.         exit(20);
  161.     }
  162.  
  163.     AslBase = OpenLibrary("asl.library",38);
  164. }
  165.  
  166. /* Do platform-dependent cleanup. */
  167. void
  168. gp_exit(int exit_status, int code)
  169. {
  170.     cleanup();
  171. }
  172.  
  173. /* ADDED by JvdW for GS3.51 */
  174. /* Exit the program. */
  175. void
  176. gp_do_exit(int exit_status)
  177. {    exit(exit_status);
  178. }
  179.  
  180. /* Read the current user CPU time (in seconds) */
  181. /* and fraction (in nanoseconds).  */
  182. void
  183. gp_get_usertime(long *pdt)
  184. {
  185. #if use_times_for_usertime
  186.     LONG secs, micros;
  187.  
  188.     CurrentTime(&secs, µs);
  189.  
  190.     pdt[0] = secs;
  191.     pdt[1] = micros*1000;
  192. #else
  193.     gp_get_clock(pdt);    /* Use an approximation on other hosts.  */
  194. #endif
  195. }
  196.  
  197. /* /ADDED */
  198.  
  199. /* ------ Miscellaneous ------ */
  200.  
  201. /* Get the string corresponding to an OS error number. */
  202. /* Unix systems support this so inconsistently that we don't attempt */
  203. /* to figure out whether it's available. */
  204. const char *
  205. gp_strerror(int errnum)
  206. {    return NULL;
  207. }
  208.  
  209. /* ------ Date and time ------ */
  210.  
  211. /* Read the current date (in days since Jan. 1, 1980) */
  212. /* and time (in milliseconds since midnight). */
  213. void
  214. gp_get_clock(long *pdt)
  215. {
  216.     struct DateStamp Date;
  217.     LONG secs, micros;
  218.  
  219.     CurrentTime(&secs, µs);
  220.  
  221.     pdt[0] = secs;
  222.     pdt[1] = micros*1000;
  223.  
  224.     DateStamp(&Date);
  225. /*
  226.     pdt[0] = Date . ds_Days + 2 * 365;
  227.     pdt[1] = (Date . ds_Minute * 60 + Date . ds_Tick / TICKS_PER_SECOND) * 1000;
  228. */
  229. }
  230.  
  231. /* ------ Screen management ------ */
  232.  
  233. /* Get the environment variable that specifies the display to use. */
  234. const char *
  235. gp_getenv_display(void)
  236. {    return getenv("DISPLAY");
  237. }
  238.  
  239. /* ------ Printer accessing ------ */
  240.  
  241. /* Open a connection to a printer.  A null file name means use the */
  242. /* standard printer connected to the machine, if any. */
  243. /* "|command" opens an output pipe. */
  244. /* Return NULL if the connection could not be opened. */
  245. FILE *
  246. gp_open_printer(char *fname, int binary_mode)
  247. {
  248. #ifndef IXEMUL
  249.     return
  250.       (strlen(fname) == 0 ?
  251.        gp_open_scratch_file(gp_scratch_file_name_prefix, fname, "w") :
  252.        fname[0] == '|' ?
  253.        NULL :
  254.        fopen(fname, "w"));
  255. #else
  256.     return
  257.       (strlen(fname) == 0 ?
  258.        gp_open_scratch_file(gp_scratch_file_name_prefix, fname, "w") :
  259.        fname[0] == '|' ?
  260.        popen(fname + 1, "w") :
  261.        fopen(fname, "w"));
  262. #endif
  263. }
  264.  
  265. /* Close the connection to the printer. */
  266. void
  267. gp_close_printer(FILE *pfile, const char *fname)
  268. {
  269. #ifndef IXEMUL
  270.     fclose(pfile);
  271. #else
  272.     if ( fname[0] == '|' )
  273.         pclose(pfile);
  274.     else
  275.         fclose(pfile);
  276. #endif
  277. }
  278.  
  279.  
  280. /* ------ File name syntax ------ */
  281.  
  282. /* Define the character used for separating file names in a list. */
  283. const char gp_file_name_list_separator = ',';
  284.  
  285. /* Define the default scratch file name template. */
  286. const char gp_scratch_file_name_prefix[] = "T:gs_";
  287.  
  288. /* Define the string to be concatenated with the file mode */
  289. /* for opening files without end-of-line conversion. */
  290. const char gp_fmode_binary_suffix[] = "";
  291. /* Define the file modes for binary reading or writing. */
  292. const char gp_fmode_rb[] = "r";
  293. const char gp_fmode_wb[] = "w";
  294.  
  295. /* Create and open a scratch file with a given name prefix. */
  296. /* Write the actual file name at fname. */
  297. FILE *
  298. gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
  299. {
  300. #ifndef IXEMUL
  301.     char *temp;
  302.     char temp2[100];
  303.     struct Task *thistask;
  304.     LONG secs, micros;
  305. #endif
  306.  
  307.     strcpy(fname,prefix);
  308.     /* Prevent trailing X's in path from being converted by mktemp. */
  309.     if ( *fname != 0 && fname[strlen(fname) - 1] == 'X' )
  310.         strcat(fname, "-");
  311. #ifdef IXEMUL
  312.     strcat(fname, "XXXXXX");
  313. #else
  314.     CurrentTime(&secs, µs);
  315.     sprintf(temp2,"%lx",FindTask(NULL));
  316.     strcat(fname, temp2);
  317. #endif
  318. #ifdef IXEMUL
  319.     mktemp(fname);
  320. #endif
  321.     return fopen(fname, mode);
  322. }
  323.  
  324. /* Answer whether a file name contains a directory/device specification, */
  325. /* i.e. is absolute (not directory- or device-relative). */
  326. int
  327. gp_file_name_is_absolute(const char *fname, uint len)
  328. {
  329.     int i;
  330.  
  331.     for(i = 0 ; i < len ; i++)
  332.     {
  333.         if(fname[i] == ':')
  334.             return(1);
  335.     }
  336.  
  337.     return(0);
  338. }
  339.  
  340. /* Answer the string to be used for combining a directory/device prefix */
  341. /* with a base file name.  The file name is known to not be absolute. */
  342. const char *
  343. gp_file_name_concat_string(const char *prefix, uint plen, const char *fname, uint len)
  344. {
  345. #ifdef IXEMUL
  346.     if(plen > 0 && (prefix[plen - 1] == '/' || prefix[plen - 1] == ':'))
  347.         return("");
  348.     else
  349.         return("/");
  350. #else
  351.     if(plen > 0)
  352.         if(prefix[plen - 1] == '/' || prefix[plen - 1] == ':')
  353.             return("");
  354.         else
  355.             return("/");
  356.     else
  357.         return("");
  358. #endif
  359. }
  360.  
  361. /* ------ File operations ------ */
  362.  
  363. /* If the file given by fname exists, fill in its status and return 1; */
  364. /* otherwise return 0. */
  365. int
  366. gp_file_status(const char *fname, struct stat *pstat)
  367. {
  368.     if ( stat((char *)fname, pstat) < 0 ) return 0;
  369.     return 1;
  370. }
  371.  
  372. /* ADDED by JvdW for GS3.51 */
  373. /* Open a file with the given name, as a stream of uninterpreted bytes. */
  374. FILE *
  375. gp_fopen(const char *fname, const char *mode)
  376. {    return fopen(fname, mode);
  377. }
  378. /* /ADDED */
  379.  
  380. /* ------ File enumeration ------ */
  381.  
  382. /****** THIS IS NOT SUPPORTED ON UNIX SYSTEMS. ******/
  383. /* Amazingly enough, there is no standard Unix library routine */
  384. /* for enumerating the files matching a pattern, */
  385. /* or even for enumerating (conveniently) the files in a directory. */
  386.  
  387. struct file_enum_s {
  388.     char *pattern;
  389.     int first_time;
  390.     const gs_memory_t *mprocs;
  391. };
  392.  
  393. /* Initialize an enumeration.  NEEDS WORK ON HANDLING * ? \. */
  394. file_enum *
  395. gp_enumerate_files_init(const char *pat, uint patlen,
  396.   gs_memory_t *mprocs)
  397. {    file_enum *pfen = (file_enum *)gs_alloc_bytes(mprocs,sizeof(file_enum), "gp_enumerate_files");
  398.     char *pattern;
  399.     if ( pfen == 0 ) return 0;
  400.     pattern = gs_alloc_bytes(mprocs,patlen + 1,"gp_enumerate_files(pattern)");
  401.     if ( pattern == 0 ) return 0;
  402.     memcpy(pattern, pat, patlen);
  403.     pattern[patlen] = 0;
  404.     pfen->pattern = pattern;
  405.     pfen->mprocs = mprocs;
  406.     pfen->first_time = 1;
  407.     return pfen;
  408. }
  409.  
  410. /* Enumerate the next file. */
  411. /* PUNT: JUST RETURN THE PATTERN. */
  412. uint
  413. gp_enumerate_files_next(file_enum *pfen, char *ptr, uint maxlen)
  414. {    if ( pfen->first_time )
  415.     {    char *pattern = pfen->pattern;
  416.         uint len = strlen(pattern);
  417.         pfen->first_time = 0;
  418.         if ( len > maxlen )
  419.             return maxlen + 1;
  420.         strcpy(ptr, pattern);
  421.         return len;
  422.     }
  423.     return -1;
  424. }
  425.  
  426. /* Clean up the file enumeration. */
  427. void
  428. gp_enumerate_files_close(file_enum *pfen)
  429. {    const gs_memory_t *mprocs = pfen->mprocs;
  430.     gs_free_object(mprocs,pfen->pattern,"gp_enumerate_files_close(pattern)");
  431.     gs_free_object(mprocs,(char *)pfen,"gp_enumerate_files_close");
  432. }
  433.  
  434. /***************************************************************************/
  435. /*         Functions from ixemul.library source which aren't in Libnix     */
  436. /***************************************************************************/
  437. #ifndef IXEMUL
  438.  
  439. /***************************************************************************/
  440. /*                                     modf.c                              */
  441. /***************************************************************************/
  442. #include <proto/mathieeedoubbas.h>
  443.  
  444. /*
  445.  * modf(value, iptr): return fractional part of value, and stores the
  446.  * integral part into iptr (a pointer to double).
  447.  */
  448.  
  449. double
  450. modf (double value, double *iptr)
  451. {
  452.   /* if value negative */
  453.   if (IEEEDPTst (value) < 0)
  454.     {
  455.       /* in that case, the integer part is calculated by ceil() */
  456.       *iptr = IEEEDPCeil (value);
  457.       return IEEEDPSub (*iptr, value);
  458.     }
  459.   else
  460.     {
  461.  
  462.       /* if positive, we go for the floor() */
  463.       *iptr = IEEEDPFloor (value);
  464.       return IEEEDPSub (value, *iptr);
  465.     }
  466. }
  467. /***************************************************************************/
  468. /*                                     frexp.c                             */
  469. /***************************************************************************/
  470. #if defined(LIBC_SCCS) && !defined(lint)
  471. static char sccsid[] = "@(#)frexp.c    5.2 (Berkeley) 3/9/86";
  472. #endif LIBC_SCCS and not lint
  473.  
  474. #define KERNEL
  475. /*#include "ixemul.h"*/
  476.  
  477. /*
  478.  *    the call
  479.  *        x = frexp(arg,&exp);
  480.  *    must return a double fp quantity x which is <1.0
  481.  *    and the corresponding binary exponent "exp".
  482.  *    such that
  483.  *        arg = x*2^exp
  484.  *    if the argument is 0.0, return 0.0 mantissa and 0 exponent.
  485.  */
  486.  
  487. double
  488. frexp(double x, int *i)
  489. {
  490.   int neg;
  491.   int j;
  492.  
  493.   j = 0;
  494.   neg = 0;
  495.  
  496.   if (x < 0)
  497.     {
  498.       x = -x;
  499.       neg = 1;
  500.     }
  501.  
  502.   if (x >= 1.0)
  503.     while(x >= 1.0)
  504.       {
  505.     j = j+1;
  506.     x = x/2;
  507.       }
  508.   else if(x < 0.5 && x != 0.0)
  509.     while(x < 0.5)
  510.       {
  511.     j = j-1;
  512.     x = 2*x;
  513.       }
  514.  
  515.   *i = j;
  516.   if (neg) x = -x;
  517.   return x;
  518. }
  519.  
  520. /***************************************************************************/
  521. /*                                     ldexp.c                             */
  522. /***************************************************************************/
  523. /*
  524.  * ldexp returns the quanity "value" * 2 ^ "exp"
  525.  *
  526.  * For the mc68000 using IEEE format the double precision word format is:
  527.  *
  528.  * WORD N   =>    SEEEEEEEEEEEMMMM
  529.  * WORD N+1 =>    MMMMMMMMMMMMMMMM
  530.  * WORD N+2 =>    MMMMMMMMMMMMMMMM
  531.  * WORD N+3 =>    MMMMMMMMMMMMMMMM
  532.  *
  533.  * Where:          S  =>   Sign bit
  534.  *                 E  =>   Exponent
  535.  *                 X  =>   Ignored (set to 0)
  536.  *                 M  =>   Mantissa bit
  537.  *
  538.  * NOTE:  Beware of 0.0; on some machines which use excess 128 notation for the
  539.  * exponent, if the mantissa is zero the exponent is also.
  540.  *
  541.  */
  542.  
  543. #define MANT_MASK 0x800FFFFF    /* Mantissa extraction mask     */
  544. #define ZPOS_MASK 0x3FF00000    /* Positive # mask for exp = 0  */
  545. #define ZNEG_MASK 0x3FF00000    /* Negative # mask for exp = 0  */
  546.  
  547. #define EXP_MASK 0x7FF00000    /* Mask for exponent            */
  548. #define EXP_SHIFTS 20        /* Shifts to get into LSB's     */
  549. #define EXP_BIAS 1023        /* Exponent bias                */
  550.  
  551.  
  552. union dtol
  553. {
  554.   double dval;
  555.   int ival[2];
  556. };
  557.  
  558. double
  559. ldexp (value, exp)
  560.      double value;
  561.      int exp;
  562. {
  563.   union dtol number;
  564.   int *iptr, cexp;
  565.  
  566.   if (value == 0.0)
  567.     return (0.0);
  568.   else
  569.     {
  570.       number.dval = value;
  571.       iptr = &number.ival[0];
  572.       cexp = (((*iptr) & EXP_MASK) >> EXP_SHIFTS) - EXP_BIAS;
  573.       *iptr &= ~EXP_MASK;
  574.       exp += EXP_BIAS;
  575.       *iptr |= ((exp + cexp) << EXP_SHIFTS) & EXP_MASK;
  576.       return (number.dval);
  577.     }
  578. }
  579. #endif
  580.